今天要來說為什麼 Hash 的 key 比較適合用 symbol,而不是 string!
原因有 2 個:
前面在解說「字串」和「符號」的時候,其實會覺得這兩個東西很雷同,這想法沒有錯,但是嚴格來說是「符號(symbol)類似無法更改的字串(string)」,那我們就來嘗試改寫字串和符號
content = "我們是Ruby工程師"
content[0..1] = 我
puts content
# 執行結果
# 我是Ruby工程師
car = :ferrari
car[3..4] = "ar"
puts car
# 出現錯誤訊息 undefined method `[]=' for :ferarri:Symbol (NoMethodError)
:ferrari
是 Symbol 這個類別的實體,而 Symbol 類別是沒有[]
這個方法,其實錯誤訊息已經提示這件事了~
Ruby 是物件導向程式語言,在 Ruby 世界中,幾乎所有東西都是物件(但也有例外,像是 block 就不是物件),所以 Ruby 在處理物件的時候,會在記憶體中找位置存放物件,可以透過這個方法object_id
找到物件所在的位置:
puts "記憶體位置:#{1.object_id}"
# 執行結果
# 記憶體位置:3
而為了證明字串、符號的效能差異,我各執行 3 次:
'hello'
3.times do
puts "記憶體位置:#{'hello'.object_id}"
end
# 執行結果
# 記憶體位置:70368301133720
# 記憶體位置:70368301133640
# 記憶體位置:70368301133560
:hello
3.times do
puts "記憶體位置:#{:hello.object_id}"
end
# 執行結果
# 記憶體位置:1059548
# 記憶體位置:1059548
# 記憶體位置:1059548
由此可見,每一次執行字串時,Ruby 就會視為不同的物件,存放在不同的位置,反觀符號執行了三次都找到同一個object_id,所以相對來說符號的效能確實比字串高,也許3筆沒什麼差異,當資料量高達幾百萬筆就很可觀了~
※ object_id
=> Returns an integer identifier for obj
根據上述第 2 點,當程式碼中大量重複使用相同的字串時,建議改用變數的方式儲存資料內容,因為變數也是指向同一個物件,可以達到降低使用 Ruby 的負擔喔!
content = "I'am a programmer."
3.times do
puts "記憶體位置:#{content.object_id}"
end
# 執行結果
# 記憶體位置:70368540742140
# 記憶體位置:70368540742140
# 記憶體位置:70368540742140
參考資料:
為你自己學Ruby on Rails-高見龍
小殘的程式光廊:Ruby教學 - 符號(Symbol)
nkj20932:Ruby on Rails 花招百出系列
學無止盡,每天都要進步一點點!